﻿using Infrastructure;
using Inspection.Helper;
using SuperSimpleTcp;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Vision.AlgBase;
using Xceed.Wpf.Toolkit.Primitives;

namespace Inspection.Views
{
    /// <summary>
    /// UCAlgManger.xaml 的交互逻辑
    /// </summary>
    public partial class UCAlgManger : UserControl, INotifyPropertyChanged
    {
        public UCAlgManger()
        {
            InitializeComponent();
            CommandBindings.Add(new CommandBinding(RunCommand, Run_Excute, Edit_CanExcute));
            CommandBindings.Add(new CommandBinding(DelteCommand, delte_Excute, Edit_CanExcute));
        }

        public static DependencyProperty AlgListProperty = DependencyProperty.Register("AlgList", typeof(IList<IAlg>), typeof(UCAlgManger), new FrameworkPropertyMetadata(new ObservableCollection<IAlg>(), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
        public static RoutedCommand RunCommand = new RoutedCommand();
        public static RoutedCommand DelteCommand = new RoutedCommand();


        public IList<IAlg> AlgList
        {
            get { return (IList<IAlg>)GetValue(AlgListProperty); }
            set { SetValue(AlgListProperty, value); }
        }

        public IAlg SelectedStep
        {
            get { return selectedStep; }
            set { selectedStep = value; OnPropertyChanged(); }
        }
        private IAlg selectedStep = null;

        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged([CallerMemberName] string PropertyName = null)
        {
            if (null != PropertyChanged)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
            }
        }
        #endregion INotifyPropertyChanged

        private void list_Drop(object sender, DragEventArgs e)
        {
            ServiceMetaData dragServiceObject = e.Data.GetData(typeof(ServiceMetaData)) as ServiceMetaData;
            if (dragServiceObject == null || dragServiceObject.StepService == null)
            {
                Debug.WriteLine("unknow object type");
                return;
            }
            DropItem = (IAlg)dragServiceObject.StepService.Clone();
            DropItem.Name = $"{dragServiceObject.SeriveName}_{AlgList.Count}";
            if (DropItem != null)
            {
                DependencyObject element = e.OriginalSource as DependencyObject;
                ListBoxItem nearItem = GetNearTreeItem<ListBoxItem>(element);
                if (nearItem != null)
                {
                    nearStep = nearItem.DataContext as IAlg;
                    ContextMenu ConMenu = (ContextMenu)TryFindResource("DropContextMenu");
                    ConMenu.PlacementTarget = sender as Button;
                    ConMenu.IsOpen = true;
                }
                else if (nearItem == null && null != AlgList)
                {
                    AlgList.Add(DropItem);
                    DropItem = null;
                }
            }
        }

        /// <summary>
        /// 添加到上一节点按键
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void AddToPreview_Click(object sender, RoutedEventArgs e)
        {
            AddToNearStep(DropItem, nearStep, false);
            nearStep = null;
            DropItem = null;
        }

        /// <summary>
        /// 添加到下一节点按键
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void AddToNext_Click(object sender, RoutedEventArgs e)
        {
            AddToNearStep(DropItem, nearStep, true);
            nearStep = null;
            DropItem = null;
        }

        /// <summary>
        /// 将加节点添加到附近的上一个节点或者下一个节点
        /// </summary>
        /// <param name="AddStep">要添加的节点</param>
        /// <param name="NearStep">附近的节点</param>
        /// <param name="IsAddToNext">是否添加到下一节点</param>
        private void AddToNearStep(IAlg AddStep, IAlg NearStep, bool IsAddToNext = false)
        {
            if (NearStep == null || null == AddStep)
            {
                return;
            }

            int Index = AlgList.IndexOf(NearStep);
            if (Index < 0)
                return;
            if (IsAddToNext)
                Index += 1;
            AlgList.Insert(Index, AddStep);
        }

        /// <summary>
        /// 根据鼠标所在的点获取树形的节点
        /// </summary>
        /// <param name="inputelement">鼠标所在的地点</param>
        /// <returns>树形节点</returns>
        private T GetNearTreeItem<T>(DependencyObject inputelement) where T : DependencyObject
        {
            T selcetedItem = inputelement as T;
            while (inputelement != null && selcetedItem == null)
            {
                inputelement = VisualTreeHelper.GetParent(inputelement) as DependencyObject;
                selcetedItem = inputelement as T;
            }
            return selcetedItem;
        }

        private void Run_Excute(object sender, ExecutedRoutedEventArgs e)
        {
            selectedStep.Run();
        }

        private void Edit_CanExcute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = selectedStep != null;
        }

        private void delte_Excute(object sender, ExecutedRoutedEventArgs e)
        {
            AlgList.Remove(selectedStep);
        }

        private IAlg DropItem;
        private IAlg nearStep;
    }
}
